/**
 *@html common.multiPopup
 *@description 通用多选弹出框js实现
 *
 *@since 2011-11-17
 */

Ccay.Module.define("Ccay.Component.ComparaLog",function(page,$S){
	objInit = new Object();
	//颜色常量.
	var GREEN = "div_green_font",BLUE = "div_blue_font",PURPLE = "div_purple_font",WHITE = "div_white_font";
	var PROPERTYNAME = "propertyName",PROPERTYVALUE="propertyValue",PROPERTYTYPE="propertyType";
	var SIMPLEPROPERTY ="simpleProperty",SIMPLEOBJECT="simpleObject",ARRAY="array";
	
	page.init = function(param,model){
		// 判断该参数模式，是否已经有对于的初始化方法，如果有，则调用其对应的初始化方法，否则记录错误日志
		if($.isFunction(objInit[model])){
			objInit[model](param)
		}else{
			Ccay.log("没有找到模式“"+model+"”对应的初始化方法.",Ccay.LOG_WARN);
		}
	};
	
	/**
	 *@description  新增模式，页面初始化方法（已闭包）
	 *@param {object} htmlArea
	 */
	objInit.compareLog = function(param){
		/*
			1:根据module和objectId获取当前版本和上一版本的message信息.
			2:用当前版本message以上一版本message作为参照，画出当前版本提示区信息.
			3:用上一版本message以当前版本message作为参照，画出上一版本提示区信息.
		*/
		Ccay.doGet("services/ccay/logs/log/single",param,
			function(pagedResult){
				if(pagedResult!=null && pagedResult.length == 2 ){
					/*存在上一版本*/
					compareTowLog($.parseJSON(pagedResult[0].message).formatLog,$.parseJSON(pagedResult[1].message).formatLog);
				}else{
					//-------------定义数据存储变量--------------------------//
					//curXPathList属性完整路径.
					var curXPathList = new Array();
					//curOjbectNodes各属性对象集合.
					var curOjbectNodes = new Ccay.HashMap();
					//curRootPropertyNames第一层属性名.
					var curRootPropertyNames = new Array();	
					//存放当前版本messaeg解析后的属性名与属性值对照关系.Map中格式（属性在message中的完整路径/属性值）
					var curLogPropertyValues = new Ccay.HashMap();		
					//集合元素属性打平后的值(AA:aa;BB:bb).
					var currentVersionElementAttributes = new Ccay.HashMap();	
					//--------------解析JSON数据,生成页面UI------------------//
					var currentLogMessage = $.parseJSON(pagedResult[0].message).formatLog;
					parsePropertyPath(curXPathList,"",currentLogMessage);
					getPropertyValue(currentLogMessage,curXPathList,curOjbectNodes,curRootPropertyNames,currentVersionElementAttributes);
					buildUI2(curOjbectNodes,currentVersionElementAttributes);
				}
			});
	};
	function compareTowLog(currentLogMessage,previousLogMessage){
		//-------------定义数据存储变量--------------------------//
		//curXPathList属性完整路径.
		var curXPathList = new Array();
		var previousXPathList = new Array();
		//curOjbectNodes各属性对象集合.
		var curOjbectNodes = new Ccay.HashMap();
		//curRootPropertyNames第一层属性名.
		var curRootPropertyNames = new Array();
		//存放当前版本messaeg解析后的属性名与属性值对照关系.Map中格式（属性在message中的完整路径/属性值）
		var curLogPropertyValues = new Ccay.HashMap();
		//集合元素属性打平后的值(AA:aa;BB:bb).
		var currentVersionElementAttributes = new Ccay.HashMap();
		//previousObjectNodes各属性对象集合.
		var previousObjectNodes = new Ccay.HashMap();
		//存放当前版本messaeg解析后的属性名与属性值对照关系.Map中格式（属性在message中的完整路径/属性值）
		var previousLogPropertyValues = new Ccay.HashMap();
		//previousRootPropertyNames第一层属性名.
		var previousRootPropertyNames = new Array();
		//集合元素属性打平后的值(AA:aa;BB:bb).
		var previousVersionElementAttributes = new Ccay.HashMap();
		
		//--------------解析JSON数据，对比两个版本生成页面UI------------------//
		//解析message,生成属性在message JSON数据中的完整路径.
		parsePropertyPath(curXPathList,"",currentLogMessage);
		parsePropertyPath(previousXPathList,"",previousLogMessage);
		getPropertyValue(currentLogMessage,curXPathList,curOjbectNodes,curRootPropertyNames,currentVersionElementAttributes);
		getPropertyValue(previousLogMessage,previousXPathList,previousObjectNodes,previousRootPropertyNames,previousVersionElementAttributes);
		var versionPropertyValues = compare(curRootPropertyNames,previousRootPropertyNames,curOjbectNodes,previousObjectNodes);
		//构建版本比较UI.
		buildUI(versionPropertyValues,currentVersionElementAttributes,previousVersionElementAttributes);
	};
	
	
	/**
	 * cmerge:当前版本message中的第一层属性名集合.
	 * pmerge：上一版本message中的第一层属性名集合.
	 * 
	 * 比较当前版本message解析后Map和上一版本message解析后的Map，
	 * 差集部分用各个元素都为Null的属性填充.主要用于构建页面时
	 * 保证排版.
	 */
	function buildUI2(curOjbectNodes,currentVersionElementAttributes){
		var curHtmlString = new Array();
		curOjbectNodes.each(function(key,value,i){
			var level = key.split(".").length;
			if(value.get(PROPERTYTYPE) == SIMPLEPROPERTY){
				if(key.indexOf("[")>-1 && key.indexOf("]")>-1){
					var substr = key.substring(0,key.indexOf("]")+1);
					if(currentVersionElementAttributes.get(substr) != null){
						var attributestr = currentVersionElementAttributes.get(substr);
						//当前版本中的此属性为新增.
						temp = spellString(WHITE,level,"",attributestr.join(";"),false,true);
						currentVersionElementAttributes.remove(substr);
					}else{
						temp = "";
					}
				}else{
					temp = spellString(WHITE,level,value.get(PROPERTYNAME),value.get(PROPERTYVALUE),true,true);
				}
			}else if(value.get(PROPERTYTYPE) == SIMPLEOBJECT){
				//简单对象类型.
				if(key.indexOf("[")<0 && key.indexOf("]")<0){
					temp =  spellString(WHITE,level,value.get(PROPERTYNAME),"",true,false);
				}else{
					temp = oldtemp =  "";
				}
			}else if(value.get(PROPERTYTYPE) == ARRAY){
				//数组类型.
				temp =  spellString(WHITE,level,value.get(PROPERTYNAME),"",true,false);
			}
			curHtmlString.push(temp);
		});
		$("#curLogInfo").append(curHtmlString.join(" "));
		$("#previousLogInfo").append(" No Log found");
		
	}
	function compare(cmerge,pmerge,curOjbectNodes,previousObjectNodes){
		var versionPropertyValues = new Array();
		
		var ccmerger = new Ccay.HashMap();
		var ppmerger = new Ccay.HashMap();
		
		//以Key/value存储当前版本中第一层属性的名称.主要是方便后续根据Key取值.
		var tempccmeger = new Ccay.HashMap();
		$.each( cmerge, function(index, fullPath){
			//tempccmeger存放当前版本中第一层属性名集合.
			tempccmeger.put(fullPath,fullPath);
			
			curOjbectNodes.each( function(key,value,i){
				if(key.indexOf(".")>-1){
					if(key.substring(0,key.indexOf(".")).indexOf(fullPath)>-1){
						ccmerger.put(key,value);
						if(previousObjectNodes.get(key)== "undefined" || previousObjectNodes.get(key)== null || previousObjectNodes.get(key)==""){
							//在上一版本中不存在此属性.
						ppmerger.put(key,buildObjectNode(null,null,null));
							
						}else{
							ppmerger.put(key,previousObjectNodes.get(key));
						}
					}
				}else{
					if(key.indexOf(fullPath)>-1){
						//alert("key:"+key+"-----"+"value:"+value);
						ccmerger.put(key,value);
						if(previousObjectNodes.get(key)== "undefined" || previousObjectNodes.get(key)== null || previousObjectNodes.get(key)==""){
							//在上一版本中不存在此属性.
						ppmerger.put(key,buildObjectNode(null,null,null));
							
						}else{
							ppmerger.put(key,previousObjectNodes.get(key));
						}
					}
				}
			});
			previousObjectNodes.each( function(key,value,i){
				if(key.indexOf(".")>-1){
					if(key.substring(0,key.indexOf(".")).indexOf(fullPath)>-1){
						if(ppmerger.get(key) == "undefined" || ppmerger.get(key) == null || ppmerger.get(key) == null){
						ppmerger.put(key,value);
						}
						if(curOjbectNodes.get(key) == "undefined" || curOjbectNodes.get(key)== null || curOjbectNodes.get(key)==""){
						//在上一版本中不存在此属性.
						ccmerger.put(key,buildObjectNode(null,null,null));
						}
					}
				}else{
					if(key.indexOf(fullPath)>-1){
						if(ppmerger.get(key) == "undefined" || ppmerger.get(key) == null || ppmerger.get(key) == null){
							ppmerger.put(key,value);
						}
						if(curOjbectNodes.get(key) == "undefined" || curOjbectNodes.get(key)== null || curOjbectNodes.get(key)==""){
						//在上一版本中不存在此属性.
						ccmerger.put(key,buildObjectNode(null,null,null));
						}
					}
				}
			});
		});
		
		//去除ccmerger已经存在的message中第一层属性名.
		$.each( pmerge, function(index, fieldName){
			if(tempccmeger.get(fieldName) == null){
				previousObjectNodes.each( function(key,value,i){
					if(key.indexOf(".")>-1){
						if(key.substring(0,key.indexOf(".")).indexOf(fieldName)>-1){
							ppmerger.put(key,value);
							ccmerger.put(key,buildObjectNode(null,null,null));
						}
					}else{
						if(key.indexOf(fieldName)>-1){
							ppmerger.put(key,value);
							ccmerger.put(key,buildObjectNode(null,null,null));
						}
					}
				});
			}
		});
		
		versionPropertyValues.push(ccmerger);
		versionPropertyValues.push(ppmerger);
		return versionPropertyValues;
	}
	/**
	 * isDisplayName:是否显示属性名(true/false).
	 * isDisplayValue:是否需要显示属性值(true/false).
	 * colorStyle:样式值.
	 * offset:偏移量.
	 * displayName:显示名.
	 * displayValue:显示值.
	 */
	function spellString(colorStyle,offset,displayName,displayValue,isDisplayName,isDisplayValue){
		var htmlstr = new Array();
		htmlstr.push("<div class='div_frame'>");
		htmlstr.push("<div class='"+colorStyle+"' style='padding-left: "+ offset*10+"px;'");
		htmlstr.push("<font style='font-weight:bold;'>");
		if(!isDisplayName && isDisplayValue){
			//只显示属性值.
			htmlstr.push(encode(displayValue));
			htmlstr.push("</font>");
		}else if(isDisplayName && !isDisplayValue){
			//只显示属性名.
			htmlstr.push(displayName);
			htmlstr.push("</font>:");
		}else{
			htmlstr.push(displayName);
			htmlstr.push("</font>:");
			htmlstr.push(encode(displayValue));
		}
		htmlstr.push("</div>");
		htmlstr.push("</div>");			
		return htmlstr.join(" ");
	}
	/**
	 * 返回无显示内容的HTML串.
	 */
	function getEmptyString(){
		return "<div class='div_frame'><div class='div_white_font' style='padding-left: 0px;'></div></div>";
	}
	
	function buildUI(versionPropertyValues,currentVersionElementAttributes,previousVersionElementAttributes){
		var curHtmlString = new Array();
		var previousHtmlString = new Array();
		var ccmerger = versionPropertyValues[0];
		var ppmerger = versionPropertyValues[1];
		
		//alert(ccmerger.keys.length);
		ccmerger.each(function(key,value,i){
			var level = key.split(".").length;
			//默认值.
			var temp = oldtemp = spellString(WHITE,level,value.get(PROPERTYNAME),value.get(PROPERTYVALUE));
			if(value.get(PROPERTYTYPE) == SIMPLEPROPERTY){
				//alert("key:"+key);
				if(key.indexOf("[")>-1 && key.indexOf("]")>-1){
					var substr = key.substring(0,key.indexOf("]")+1);
					if(currentVersionElementAttributes.get(substr) != null){
						var attributestr = currentVersionElementAttributes.get(substr);
						var previousAttributestr = previousVersionElementAttributes.get(substr);
						Ccay.Core.log(key+" "+attributestr)
						var color = getColorByKey(key,GREEN);
						if(ppmerger.get(key).get(PROPERTYNAME) != null && ppmerger.get(key).get(PROPERTYVALUE) != null 
								&&  ppmerger.get(key).get(PROPERTYTYPE) != null && previousVersionElementAttributes.get(substr) == null){
							var color = WHITE;
						}
						if(previousVersionElementAttributes.get(substr) != null){
							oldtemp = spellString(color,level,"",previousAttributestr.join(";"),false,true);
							//置空.
							previousVersionElementAttributes.remove(substr);
						}else{
							//填充的空值.
							oldtemp = getEmptyString();
						}
						temp = spellString(color,level,"",attributestr.join(";"),false,true);
						//置空.
						currentVersionElementAttributes.remove(substr);
						
						
					}else{
						temp = oldtemp =  "";
					}
				}
				else if(ppmerger.get(key).get(PROPERTYNAME) == null && ppmerger.get(key).get(PROPERTYVALUE) == null &&  ppmerger.get(key).get(PROPERTYTYPE) == null){
					var color = getColorByKey(key,GREEN);
					//当前版本中的此属性为新增.
					temp = spellString(color,level,value.get(PROPERTYNAME),value.get(PROPERTYVALUE));
					//填充的空值.
					oldtemp = getEmptyString();
				}else if(ppmerger.get(key).get(PROPERTYVALUE) != value.get(PROPERTYVALUE)){
					var color = getColorByKey(key,BLUE);
					//更新了属性.
					temp = spellString(color,level,value.get(PROPERTYNAME),value.get(PROPERTYVALUE));
					oldtemp = spellString(color,level,ppmerger.get(key).get(PROPERTYNAME),ppmerger.get(key).get(PROPERTYVALUE));
				}
			}else if(value.get(PROPERTYTYPE) == SIMPLEOBJECT){
				//简单对象类型.
				if(key.indexOf("[")<0 && key.indexOf("]")<0){
					if(ppmerger.get(key).get(PROPERTYNAME) == null && ppmerger.get(key).get(PROPERTYVALUE) == null &&  ppmerger.get(key).get(PROPERTYTYPE) == null){
						temp =  spellString(GREEN,level,value.get(PROPERTYNAME),"",true,false);
						oldtemp = getEmptyString();
					}else{
						temp =  spellString(WHITE,level,value.get(PROPERTYNAME),"",true,false);
						oldtemp =  spellString(WHITE,level,value.get(PROPERTYNAME),"",true,false);
					}
				}else{
					temp = oldtemp =  "";
				}
			}else if(value.get(PROPERTYTYPE) == ARRAY){
				//var color = key.indexOf("Create")>-1?GREEN:WHITE;
				var color = getColorByKey(key,null);
				//数组类型.
				if(ppmerger.get(key).get(PROPERTYNAME) == null && ppmerger.get(key).get(PROPERTYVALUE) == null &&  ppmerger.get(key).get(PROPERTYTYPE) == null){
					if(color == null){
						color = GREEN;
					}
					temp =  spellString(color,level,value.get(PROPERTYNAME),"",true,false);
					oldtemp = getEmptyString();
				}else{
					if(color == null){
						color = WHITE;
					}
					temp =  spellString(color,level,value.get(PROPERTYNAME),"",true,false);
					oldtemp =  spellString(color,level,value.get(PROPERTYNAME),"",true,false);
				}
				
				//temp =  spellString(WHITE,level,value.get(PROPERTYNAME),"",true,false);
				//oldtemp = getEmptyString();
			}else{
				//删除了属性值.
				if(key.indexOf("[")<0 && key.indexOf("]")<0){
					temp =  getEmptyString();
					var color = getColorByKey(key,PURPLE)
					oldtemp =  spellString(color,level,ppmerger.get(ppmerger.keys[i]).get(PROPERTYNAME),ppmerger.get(ppmerger.keys[i]).get(PROPERTYVALUE));
				}else if (key.indexOf("[")>-1 && key.indexOf("]")>-1){
					var substr = key.substring(0,key.indexOf("]")+1);
					if(previousVersionElementAttributes.get(substr) != null){
						var color = getColorByKey(key,PURPLE);
							var attributestr = previousVersionElementAttributes.get(substr);
							oldtemp = spellString(color,level,"",attributestr.join(";"),false,true);
							//填充的空值.
							temp = getEmptyString();
							//置空.
							previousVersionElementAttributes.remove(substr);
					}else{
						temp = oldtemp =  "";
					}
				}else{
					temp = oldtemp =  "";
				}
			}
			curHtmlString.push(temp);
			previousHtmlString.push(oldtemp);
		});
		$("#curLogInfo").append(curHtmlString.join(" "));
		$("#previousLogInfo").append(previousHtmlString.join(" "));
		
	}
	function getColorByKey(key,color){
		if(key == null){
			return color;
		}
		if(key.indexOf("items2Create")>-1){
			return GREEN;
		}else if(key.indexOf("items2Delete")>-1){
			return PURPLE;
		}else if(key.indexOf("items2Update")>-1){
			return BLUE;
		}
		return color;
	}
	/*
	 * 
	 * */
	function parsePropertyPath(propertyPaths,path,message){
		if(!$.isPlainObject(message)){
			propertyPaths.push(path);
			return;
		}
		for(var $p in message){
			var propertyName = $p;
			var propertyValue = message[$p];	
			var propertyPath  = Ccay.DataHelper.isEmpty(path)?$p: path+"."+$p;	
			//alert("propertyName:"+propertyName);
			propertyPaths.push(propertyPath);
			if((propertyValue!=null) && (typeof(propertyValue) == "object")){
				//当为数组类型时.
				if(typeof(propertyValue.length) != "undefined" && propertyValue.length>0){
					for(var index = 0;index<propertyValue.length;index++){
						//继续处理当前对象中的成员属性.
						var elementPath = propertyPath+"["+index+"]";
						parsePropertyPath(propertyPaths,elementPath,propertyValue[index]);
					}
				}else{
						//继续处理当前对象中的成员属性.
						parsePropertyPath(propertyPaths,propertyPath,propertyValue);
				}
			}
		}
	};
	/* xPathList:message的JSON数据中的所有属性的完整路径集合.
	 * message:日志的message转换后的JSON对象.
	 * objectNodeList:存放属性对象集合.
	 * rootPropertyNames:存放message中第一层的属性名.
	 * */
	function getPropertyValue(message,xPathList,objectNodeList,rootPropertyNames,elementAttributes){
		//进行比较两个版本.
		$.each( xPathList, function(index, fullPath){
		 	var propertyNames = fullPath.split(".");
		 	//分割后长度为1的为第一层属性.
		 	if(propertyNames.length ==1){
		 		rootPropertyNames.push(fullPath);
		 	}
		 	var objectNode = message;
		 	$.each( propertyNames, function(i, propertyName){
		 		if(propertyName.indexOf("[")>-1 && propertyName.indexOf("]")>-1){
		 			//为集合类型，取集合中元素对象.
		 			var startIndex = propertyName.indexOf("[");
		 			var elementIndex = propertyName.substring(startIndex+1,propertyName.indexOf("]"));
		 			var listPropertyName = propertyName.substring(0, startIndex);
		 			objectNode = objectNode[listPropertyName][elementIndex.valueOf()];
		 		}else{
		 			objectNode = objectNode[propertyName];
		 		}
		 		
		 		if(!Ccay.DataHelper.isEmpty(objectNode)){   //如果属性值不为空值
		 			if((propertyNames.length-1)  == i && (typeof(objectNode)!="object")){
			 			//无子属性时，则为简单属性.
			 			if(objectNodeList.get(fullPath)==null){
			 				objectNodeList.put(fullPath,buildObjectNode(propertyName,objectNode,SIMPLEPROPERTY));
			 			}
			 			//如果为List中的简单属性类型，则将List中的元素的所有属性打平显示.
			 			if(fullPath.indexOf("[")>-1 && fullPath.indexOf("]")>-1){
			 				var index = fullPath.indexOf("]");
			 				var key = fullPath.substring(0,index+1);
			 				if(elementAttributes.get(key) == null){
			 					elementAttributes.put(key,new Array());
			 				}
			 				elementAttributes.get(key).push(propertyName+":"+objectNode);
			 				
			 			}
		 			}else{
		 				Ccay.Core.log(propertyName)
			 			//集合类型处理.
			 			if(objectNode!= null && typeof(objectNode) == "object" && objectNode.length>0){
			 				objectNodeList.put(fullPath,buildObjectNode(propertyName,"",ARRAY));
			 			}
			 			else{
			 				//简单对象类型处理.
			 				var index = fullPath.indexOf(propertyName);
			 				var substr = fullPath.substring(0,index+propertyName.length);
			 				
			 				if(objectNodeList.get(substr)==null && objectNode!=null){
			 					objectNodeList.put(substr,buildObjectNode(propertyName,"",SIMPLEOBJECT));
			 				}
			 			}
		 			}
		 		}
		 	}); 
		}); 
	};
	
	
	/*参数：
	 *	propertyName:属性名
	 *	propertyValue:属性值.
	 *	type:属性数据类型标识.
	 *return:
	 *	存储了属性细信息的Array.
	 * */
	function buildObjectNode(propertyName,propertyValue,type){
		var node = new Ccay.HashMap();
		node.put(PROPERTYNAME,propertyName);
		node.put(PROPERTYVALUE,propertyValue);
		node.put(PROPERTYTYPE,type);
		return node;
	}
});

